/* eslint-disable @typescript-eslint/no-loss-of-precision */

import { describe, expect, it } from 'vitest'

import {
  boundRange,
  decimalLength,
  divide,
  doubleDigits,
  formatByteSize,
  isValidNumber,
  leaveNumber,
  minus,
  multipleFixed,
  padStartZeros,
  plus,
  round,
  segmentNumber,
  times,
  toFixed,
  toNumber,
  toPrecision
} from '../src'

describe('number', () => {
  it('isValidNumber', () => {
    expect(isValidNumber('123')).toBe(true)
    expect(isValidNumber('abc')).toBe(false)
    expect(isValidNumber('')).toBe(true)
    expect(isValidNumber('', true)).toBe(false)
    expect(isValidNumber('+123')).toBe(true)
    expect(isValidNumber('-123')).toBe(true)
    expect(isValidNumber('+')).toBe(false)
    expect(isValidNumber('-')).toBe(false)
    expect(isValidNumber('123.')).toBe(true)
    expect(isValidNumber('123.45')).toBe(true)
    expect(isValidNumber('.45')).toBe(true)
    expect(isValidNumber('+.45')).toBe(true)
    expect(isValidNumber('-.45')).toBe(true)
    expect(isValidNumber(' 123')).toBe(true)
    expect(isValidNumber('123 ')).toBe(true)
    expect(isValidNumber(' 123 ')).toBe(true)
    expect(isValidNumber(' +123.45 ')).toBe(true)
    expect(isValidNumber('- 123')).toBe(false)
    expect(isValidNumber('123abc')).toBe(true)
    expect(isValidNumber('123abc', true)).toBe(false)
    expect(isValidNumber('abc123')).toBe(false)
    expect(isValidNumber('1e10')).toBe(true)
    expect(isValidNumber('1e10', true)).toBe(true)
    expect(isValidNumber('1.2e10', true)).toBe(true)
    expect(isValidNumber('1e-10', true)).toBe(true)
    expect(isValidNumber('1.45e+10', true)).toBe(true)
    expect(isValidNumber('1.2e+1.0')).toBe(true)
    expect(isValidNumber('1e+1.0', true)).toBe(false)
    expect(isValidNumber(new Date())).toBe(true)
    expect(isValidNumber(new Date(), true)).toBe(false)
  })

  it('toNumber', () => {
    expect(toNumber('123')).toBe(123)
    expect(toNumber('abc')).toBe(0)
    expect(toNumber('')).toBe(0)
    expect(toNumber('+123')).toBe(123)
    expect(toNumber('-123')).toBe(-123)
    expect(toNumber('+')).toBe(0)
    expect(toNumber('-')).toBe(0)
    expect(toNumber('123.')).toBe(123)
    expect(toNumber('123.45')).toBe(123.45)
    expect(toNumber('.45')).toBe(0.45)
    expect(toNumber('+.45')).toBe(0.45)
    expect(toNumber('-.45')).toBe(-0.45)
    expect(toNumber(' 123')).toBe(123)
    expect(toNumber('123 ')).toBe(123)
    expect(toNumber(' 123 ')).toBe(123)
    expect(toNumber(' +123.45 ')).toBe(123.45)
    expect(toNumber('- 123')).toBe(0)
    expect(toNumber('123abc')).toBe(123)
    expect(toNumber('abc123')).toBe(0)

    const date = new Date()
    expect(toNumber(date)).toBe(date.getTime())
  })

  it('padStartZeros', () => {
    expect(padStartZeros(5, 2)).toEqual('05')
    expect(padStartZeros(-5, 3)).toEqual('-005')
    expect(padStartZeros(15, 1)).toEqual('15')
    expect(padStartZeros(-15, 4)).toEqual('-0015')
    expect(padStartZeros(1.5, 3)).toEqual('002')
  })

  it('doubleDigits', () => {
    expect(doubleDigits(5)).toEqual('05')
    expect(doubleDigits(-5)).toEqual('-05')
    expect(doubleDigits(15)).toEqual('15')
    expect(doubleDigits(-15)).toEqual('-15')
  })

  it('decimalLength', () => {
    expect(decimalLength(123)).toBe(0)
    expect(decimalLength(1.23)).toBe(2)
    expect(decimalLength('1.23')).toBe(2)
    expect(decimalLength(0.123)).toBe(3)
    expect(decimalLength(1e-5)).toBe(5)
    expect(decimalLength(1e-5)).toBe(5)
    expect(decimalLength('1e-5')).toBe(5)
    expect(decimalLength('1E-5')).toBe(5)
    expect(decimalLength(1.23e-5)).toBe(7)
    expect(decimalLength('1.23e-5')).toBe(7)
    expect(decimalLength(1.23e3)).toBe(0)
    expect(decimalLength('1.23e3')).toBe(0)
  })

  it('segmentNumber', () => {
    expect(segmentNumber(123)).toEqual('123')
    expect(segmentNumber(12345)).toEqual('12,345')
    expect(segmentNumber(123.45)).toEqual('123.45')
    expect(segmentNumber(12345.67)).toEqual('12,345.67')
    expect(segmentNumber(1234567890)).toEqual('1,234,567,890')
    expect(segmentNumber(12345, 2)).toEqual('1,23,45')
    expect(segmentNumber(12345, 2, '-')).toEqual('1-23-45')
  })

  it('toFixed', () => {
    expect(toFixed(1.255, 2)).toBe(1.26)
    expect(toFixed(1.3335, 3)).toBe(1.334)
    expect(toFixed(17.2745, 2)).toBe(17.27)
    expect(toFixed(1.09, 2)).toBe(1.09)
    expect(toFixed(1.009, 2)).toBe(1.01)
    expect(toFixed(10.999, 2)).toBe(11)
    expect(toFixed(15.5, 2)).toBe(15.5)
    expect(toFixed(15.555, 2)).toBe(15.56)
    expect(toFixed(1.34e-7, 7)).toBe(1e-7)
    expect(toFixed(1.35e-7, 8)).toBe(1.4e-7)
  })

  it('multipleFixed', () => {
    expect(multipleFixed(1.2255, 10, 2)).toBe(12.26)
    expect(multipleFixed(1.333335, 100, 3)).toBe(133.334)
    expect(multipleFixed(17.2745, 0.1, 2)).toBe(1.73)
    expect(multipleFixed(1.09, 1, 2)).toBe(1.09)
    expect(multipleFixed(1.34e-7, 100, 5)).toBe(1e-5)
    expect(multipleFixed(1.35e-7, 1000, 5)).toBe(1.4e-4)
  })

  it('round', () => {
    expect(round(0.5, 0.5)).toBe(1)
    expect(round(0.5, 0.6)).toBe(0)
    expect(round(0.5, 0.4)).toBe(1)
    expect(round(1, 0.4)).toBe(1)
    expect(round(1.1, 0.1)).toBe(2)
  })

  it('boundRange', () => {
    expect(boundRange(5, 1, 10)).toBe(5)
    expect(boundRange(5, 6, 10)).toBe(6)
    expect(boundRange(5, 1, 4)).toBe(4)
  })

  it('leaveNumber', () => {
    expect(leaveNumber(12345, 10)).toEqual([1, 2, 3, 4, 5])
    expect(leaveNumber(10, 10)).toEqual([1, 0])
    expect(leaveNumber(11, 10)).toEqual([1, 1])
    expect(leaveNumber(9, 10)).toEqual([9])
    expect(leaveNumber(0, 10)).toEqual([0])
    expect(leaveNumber(123, 1)).toEqual([123])
    expect(leaveNumber(12345, 10, 3)).toEqual([12, 3, 4, 5])
    expect(leaveNumber(12, 10, 1)).toEqual([1, 2])
  })

  it('formatByteSize', () => {
    expect(formatByteSize(1024)).toBe(1024)
    expect(formatByteSize(2048)).toBe(2)
    expect(formatByteSize(2 * 1024 ** 3)).toBe(2)
    expect(formatByteSize(1024, 'KB')).toBe(1)
    expect(formatByteSize(1024 ** 2, 'MB')).toBe(1)
    expect(formatByteSize(1024 ** 3, 'GB')).toBe(1)
    expect(formatByteSize(1024 ** 4, 'TB')).toBe(1)
    expect(formatByteSize(1024, 'KB', true)).toEqual('1KB')
    expect(formatByteSize(1024 ** 2, 'MB', true)).toEqual('1MB')
    expect(formatByteSize(1024 ** 3, 'GB', true)).toEqual('1GB')
    expect(formatByteSize(1024 ** 4, 'TB', true)).toEqual('1TB')
    expect(formatByteSize(1024 ** 4, 'AUTO', true)).toEqual('1024GB')
    expect(formatByteSize(1111, 'AUTO')).toBe(1.08)
    expect(formatByteSize(1111, 'AUTO', 3)).toBe(1.085)
    expect(formatByteSize(1111, 'AUTO', true, 3)).toEqual('1.085KB')
  })

  it('toPrecision', () => {
    expect(toPrecision(0.098, 1)).toBe(0.1)
    expect(toPrecision('0.098', 1)).toBe(0.1)
    expect(toPrecision(0.98, 1)).toBe(1)
    expect(toPrecision('0.98', 1)).toBe(1)
    expect(toPrecision(0.09999999999999998)).toBe(0.1)
    expect(toPrecision('0.09999999999999998')).toBe(0.1)
    expect(toPrecision(0.9999999999999998)).toBe(1)
    expect(toPrecision(1.0000000000000001)).toBe(1)
    expect(toPrecision('1.0000000000000001')).toBe(1)
  })

  it('times', () => {
    expect(times(0.07, 100)).toBe(7)
    expect(times(0.7, 0.1)).toBe(0.07)
    expect(times(3, 0.3)).toBe(0.9)
    expect(times(118762317358.75, 1e-8)).toBe(1187.6231735875)
    expect(times(0.362, 100)).toBe(36.2)
    expect(times(1.1, 1.1)).toBe(1.21)
    expect(times(2.018, 1000)).toBe(2018)
    expect(times(5.2, -3.8461538461538462)).toBe(-20)
    expect(times(1.22, -1.639344262295082)).toBe(-2)
    expect(times(2.5, -0.92)).toBe(-2.3)
    expect(times(-2.2, 0.6363636363636364)).toBe(-1.4)
    expect(times('0.07', '100')).toBe(7)
    expect(times('0.7', '0.1')).toBe(0.07)
    expect(times('3', '0.3')).toBe(0.9)
    expect(times('118762317358.75', '1e-8')).toBe(1187.6231735875)
    expect(times('0.362', '100')).toBe(36.2)
    expect(times('1.1', '1.1')).toBe(1.21)
    expect(times('2.018', '1000')).toBe(2018)
    expect(times('5.2', '-3.8461538461538462')).toBe(-20)
    expect(times('1.22', '-1.639344262295082')).toBe(-2)
    expect(times('2.5', '-0.92')).toBe(-2.3)
    expect(times('-2.2', '0.6363636363636364')).toBe(-1.4)
    expect(times(8.0, -0.3625)).toBe(-2.9)
    expect(times(6.6, 0.30303030303030304)).toBe(2)
    expect(times(10.0, -0.8)).toBe(-8)
    expect(times(-1.1, -7.272727272727273)).toBe(8)
    expect(times('8.0', '-0.3625')).toBe(-2.9)
    expect(times('6.6', '0.30303030303030304')).toBe(2)
    expect(times('10.0', '-0.8')).toBe(-8)
    expect(times('-1.1', '-7.272727272727273')).toBe(8)
    expect(times(-1.23e4, 20)).toBe(-246000)
    expect(times(1.7e-30, 1.5e20)).toBe(2.55e-10)
    expect(times('-1.23e4', '20')).toBe(-246000)
    expect(times('1.7e-30', '1.5e20')).toBe(2.55e-10)
    expect(times(2, 2, 3)).toBe(12)
    expect(times(2, 2, 3, 0.1)).toBe(1.2)
    expect(times('2', '2', '3')).toBe(12)
    expect(times('2', '2', '3', '0.1')).toBe(1.2)
    expect(times(0.000000123456, 0.000000123456)).toBe(1.5241383936e-14)
    expect(times(1.23456e-7, 1.23456e-7)).toBe(1.5241383936e-14)
    expect(times('0.000000123456', '0.000000123456')).toBe(1.5241383936e-14)
    expect(times('1.23456e-7', '1.23456e-7')).toBe(1.5241383936e-14)
    expect(times(...new Array(50).fill(1))).toBe(1)
  })

  it('plus', () => {
    expect(plus(0.1, 0.2)).toBe(0.3)
    expect(plus(2.3, 2.4)).toBe(4.7)
    expect(plus(-1.6, -1)).toBe(-2.6)
    expect(plus(-2.0, 63)).toBe(61)
    expect(plus(-3, 7)).toBe(4)
    expect(plus(-221, 38)).toBe(-183)
    expect(plus(-1, 0)).toBe(-1)
    expect(plus(2.018, 0.001)).toBe(2.019)
    expect(plus(1.3224e10, 1.3224e3)).toBe(13224001322.4)
    expect(plus(1.6e-30, 1.6e-30)).toBe(3.2e-30)
    expect(plus('0.1', '0.2')).toBe(0.3)
    expect(plus('2.3', '2.4')).toBe(4.7)
    expect(plus('-1.6', '-1')).toBe(-2.6)
    expect(plus('-2.0', '63')).toBe(61)
    expect(plus('-3', '7')).toBe(4)
    expect(plus('-221', '38')).toBe(-183)
    expect(plus('-1', '0')).toBe(-1)
    expect(plus('-1', '0', '2', '3', 4)).toBe(8)
    expect(plus('2.018', '0.001')).toBe(2.019)
    expect(plus('1.3224e10', '1.3224e3')).toBe(13224001322.4)
    expect(plus('1.6e-30', '1.6e-30')).toBe(3.2e-30)
    expect(plus(0.1, 0.2, 0.3)).toBe(0.6)
    expect(plus('0.1', '0.2', '0.3')).toBe(0.6)
    expect(plus(...new Array(50).fill(1))).toBe(50)
  })

  it('minus', () => {
    expect(minus(0.07, 0.01)).toBe(0.06)
    expect(minus(0.7, 0.1)).toBe(0.6)
    expect(minus(1.0, 0.9)).toBe(0.1)
    expect(minus(1, 0)).toBe(1)
    expect(minus(1, -0)).toBe(1)
    expect(minus(-1, 0)).toBe(-1)
    expect(minus(-1, -0)).toBe(-1)
    expect(minus(1, 22)).toBe(-21)
    expect(minus(8893568.397103781249, -7.2967405955)).toBe(8893575.693844376749)
    expect(minus(105468873, 0)).toBe(105468873)
    expect(minus('0.07', '0.01')).toBe(0.06)
    expect(minus('0.7', '0.1')).toBe(0.6)
    expect(minus('1.0', '0.9')).toBe(0.1)
    expect(minus('1', '0')).toBe(1)
    expect(minus('1', '-0')).toBe(1)
    expect(minus('-1', '0')).toBe(-1)
    expect(minus('-1', '-0')).toBe(-1)
    expect(minus('1', '22')).toBe(-21)
    expect(minus('8893568.397103781249', '-7.29674059550')).toBe(8893575.693844376749)
    expect(minus('105468873', '0')).toBe(105468873)
    expect(minus(1.23e5, 10)).toBe(122990)
    expect(minus(1.23e-5, 1.0023)).toBe(-1.0022877)
    expect(minus(1.3224e10, 21)).toBe(13223999979)
    expect(minus(1.3224e10, 1.3224e3)).toBe(13223998677.6)
    expect(minus(1.7e-30, 0.1e-30)).toBe(1.6e-30)
    expect(minus('1.23e5', '10')).toBe(122990)
    expect(minus('1.23e-5', '1.0023')).toBe(-1.0022877)
    expect(minus('1.3224e10', '21')).toBe(13223999979)
    expect(minus('1.3224e10', '1.3224e3')).toBe(13223998677.6)
    expect(minus('1.7e-30', '0.1e-30')).toBe(1.6e-30)
    expect(minus(6, 3, 2)).toBe(1)
    expect(minus(6, 3, 2, 1, 2, 3)).toBe(-5)
    expect(minus('6', '3', '2')).toBe(1)
    expect(minus('6', '3', '2', '1', '2', '3')).toBe(-5)
    expect(minus(50, ...new Array(50).fill(1))).toBe(0)
  })

  it('divide', () => {
    expect(divide(1.21, 1.1)).toBe(1.1)
    expect(divide(4750.49269435, 4)).toBe(1187.6231735875)
    expect(divide(0.9, 3)).toBe(0.3)
    expect(divide(36.2, 0.362)).toBe(100)
    expect(divide(-20, 5.2)).toBe(-3.8461538461538462)
    expect(divide(-2, 1.22)).toBe(-1.639344262295082)
    expect(divide(-2.3, 2.5)).toBe(-0.92)
    expect(divide(-1.4, -2.2)).toBe(0.6363636363636364)
    expect(divide(7, -3)).toBe(-2.3333333333333335)
    expect(divide(7, -0.076)).toBe(-92.10526315789471)
    expect(divide(-2.9, 8.0)).toBe(-0.3625)
    expect(divide(2, 6.6)).toBe(0.30303030303030304)
    expect(divide(-8, 10.0)).toBe(-0.8)
    expect(divide(8, -1.1)).toBe(-7.272727272727273)
    expect(divide('1.21', '1.1')).toBe(1.1)
    expect(divide('4750.49269435', '4')).toBe(1187.6231735875)
    expect(divide('0.9', '3')).toBe(0.3)
    expect(divide('36.2', '0.362')).toBe(100)
    expect(divide('-20', '5.2')).toBe(-3.8461538461538462)
    expect(divide('-2', '1.22')).toBe(-1.639344262295082)
    expect(divide('-2.3', '2.5')).toBe(-0.92)
    expect(divide('-1.4', '-2.2')).toBe(0.6363636363636364)
    expect(divide('7', '-3')).toBe(-2.3333333333333335)
    expect(divide('7', '-0.076')).toBe(-92.10526315789471)
    expect(divide('-2.9', '8.0')).toBe(-0.3625)
    expect(divide('2', '6.6')).toBe(0.30303030303030304)
    expect(divide('-8', '10.0')).toBe(-0.8)
    expect(divide('8', '-1.1')).toBe(-7.272727272727273)
    expect(divide(-1.23e4, 20)).toBe(-615)
    expect(divide(2.55e-10, 1.7e-30)).toBe(1.5e20)
    expect(divide('-1.23e4', '20')).toBe(-615)
    expect(divide('2.55e-10', '1.7e-30')).toBe(1.5e20)
    expect(divide(12, 3, 2)).toBe(2)
    expect(divide(33.3333, 100)).toBe(0.333333)
    expect(divide(83.42894732749, 100)).toBe(0.8342894732749)
    expect(divide(1, 3)).toBe(0.3333333333333333)
    expect(divide('12', '3', '2')).toBe(2)
    expect(divide('33.3333', '100')).toBe(0.333333)
    expect(divide('83.42894732749', '100')).toBe(0.8342894732749)
    expect(divide('1', '3')).toBe(0.3333333333333333)
    expect(divide(...new Array(50).fill(1))).toBe(1)
    expect(divide(1024, 4, 8, 2)).toBe(16)
  })
})
